
    public Map checkAndSplitOrder(String porderId,Double pretry, String splitType,Map ctx) {
        Map params = DaoUtils.buildParamMap("orderId",porderId,"retry",pretry);
        String orderId = getStrFromMap(params, "orderId");
        boolean isSpOutShippingNo = ctx.containsKey("isSpOutShippingNo") && (Boolean)ctx.get("isSpOutShippingNo");

//        com.alibaba.fastjson.JSONObject allMap = new com.alibaba.fastjson.JSONObject();
//        com.alibaba.fastjson.JSONObject tallMap = JSON.parseObject(org.apache.commons.io.FileUtils.readFileToString(new java.io.File(String.format("./test-all-%s.json",""))));
//        if(!tallMap.containsKey("data")){
//            allMap.put("data",tallMap);
//        }
//        else {
//            allMap = tallMap;
//        }
//        List<Map> fullAtpDbrows = ctx.containsKey("fullAtpDbrows")?(List)ctx.get("fullAtpDbrows"):(List<Map>)allMap.getJSONObject("data").get("SPLIT_ORDER_ATP_TEMP_DATA");
//        List<Map> od = ctx.containsKey("od")?(List)ctx.get("od"):(List<Map>)allMap.getJSONObject("data").get("SPLIT_ORDER_OD_TEMP_DATA");
//        List<Map> productInfo = (List<Map>)allMap.getJSONObject("data").get("SPLIT_ORDER_PRODUCTINFO_TEMP_DATA");
//        if(productInfo.isEmpty()) {
//            log.info("select pp.isshare,upper(rtrim(pp.area)) area, rtrim(t.productid) xproductid ,t.*  ,t.pallet*t.dwzl palletdwzl, t.pallet*t.dwxs palletdwxs, t.pallet*t.dwtj palletdwtj  , t.levelNumber*dwzl levelNumberdwzl, t.levelNumber*dwxs levelNumberdwxs , t.levelNumber*dwtj levelNumberdwtj  from (    select p.productid,p.prodname  ,p.pcontrol,p.isAD,p.levelNumber,  CASE  WHEN Factory = '1210' THEN p.Pallet2  ELSE p.Pallet  END AS pallet  ,Gross dwzl,Coef dwxs  ,prdsize dwtj  from product p with(nolock)    ) t  inner join product pp with(NOLOCK) on t.productid=pp.productid  where t.productid in (    '{}'    )"
//                    ,od.stream().map(r->getStrFromMap(r,"productid")).collect(Collectors.joining("','"))
//            );
//            productInfo = (List<Map>) JSON.parse(org.apache.commons.io.FileUtils.readFileToString(new java.io.File(String.format("./test-productInfo-%s.json", orderId))));
//        }
//        if(productInfo.isEmpty()){productInfo = baseMapper.productInfoWithProductIds(Arrays.asList(DaoUtils.list2map(od, true, "productid").keySet().toArray()),null);}
//        productInfo = productInfo.stream().map(r->{r.put("productid",getStrFromMap(r,"productid"));return r;}).collect(Collectors.toList());
//        Map calcAndCheckShippingQty = ((List<Map>)allMap.getJSONObject("data").get("SPLIT_ORDER_YSDWJC_TEMP_DATA")).stream().findFirst().orElse(new HashMap());
//        List<Map> transunitQtyControls = (List<Map>)allMap.getJSONObject("data").get("SPLIT_ORDER_TRANSUNIT_TEMP_DATA");

        List<Map> fullAtpDbrows = ctx.containsKey("fullAtpDbrows")?(List)ctx.get("fullAtpDbrows"):RedisUtils.getMapList(RedisKeyConstants.SPLIT_ORDER_ATP_TEMP_DATA + orderId);
        List<Map> od = ctx.containsKey("od")?(List)ctx.get("od"):RedisUtils.getMapList(RedisKeyConstants.SPLIT_ORDER_OD_TEMP_DATA + orderId);
        List<Map> shippingQtyCalcs = RedisUtils.getMapList(RedisKeyConstants.SPLIT_ORDER_YSDWJC_TEMP_DATA + orderId);
        List<Map> transunitQtyControls = RedisUtils.getMapList(RedisKeyConstants.SPLIT_ORDER_TRANSUNIT_TEMP_DATA + orderId);

        if(null==od || od.size()<=0) { //null==fullAtpDbrows || fullAtpDbrows.size()<=0 ||
            return DaoUtils.buildParamMap(
                    "pass",false
                    ,"msg","请先完成可用性检测"
            );
        }

        Map splitTypeData = null;
        try {
//            splitTypeData = (Map)allMap.getJSONObject("data").get("SPLIT_TYPE_DATA");
            splitTypeData = handleSplitType(orderId,splitType);
        } catch (Exception e) {
            return DaoUtils.buildParamMap(
                    "pass",false
                    ,"message",e.getMessage()
            );
        }
        boolean isNotInSplitTypeMode = splitTypeData==null || "1".equals(splitType);
        String pshippingno = null==splitTypeData?null:getStrFromMap(splitTypeData,"shippingNo");


        String inorderId = getStrFromMap(od.get(0), "orderid");//
        String clientid = getStrFromMap(od.get(0), "clientid");//
        String orderMasterType = getStrFromMap(od.get(0), "order_master_type");//
//        boolean isRdcX = KhUtil.isRdcOrder(orderMasterType);
        List<Map> productInfo = baseMapper.productInfoWithProductIds(Arrays.asList(DaoUtils.list2map(od, true, "productid").keySet().toArray()), KhUtil.getRdcAllotLgort(orderMasterType), orderMasterType);
        //关联分单InSplitTypeMode不检测特殊产品数量控制
        //StringUtils.isNotBlank(pshippingno)指定了分单运输方式
        boolean isNeedCalcShipping = shippingQtyCalcs.isEmpty()||StringUtils.isNotBlank(pshippingno);
        Map calcAndCheckShippingQty = isNotInSplitTypeMode?(isNeedCalcShipping ? null : shippingQtyCalcs.get(0) ) : new HashMap();
        if(isNotInSplitTypeMode && isNeedCalcShipping){
            OrderGroupItem groupOrder = SpringContextUtils.getBean(OrderGroupItemMapper.class).getGroupOrderId(orderId);
            String mainOrderId = "";
            String otherOrderIds = "";
            boolean isGroup = !org.apache.commons.lang3.StringUtils.isBlank(groupOrder.getGroupId());
            boolean hasGroupOrder = CollectionUtils.isNotEmpty(groupOrder.getGroupOrderIds());
            if(hasGroupOrder){
                mainOrderId = groupOrder.getGroupId();
                otherOrderIds = Stream.concat(Stream.of(mainOrderId,orderId),groupOrder.getGroupOrderIds().stream()).distinct().collect(Collectors.joining(","));
                calcAndCheckShippingQty = calcAndCheckShippingQtyGroup(otherOrderIds);
            }
            else {
                calcAndCheckShippingQty = calcAndCheckShippingQty(orderId,pshippingno);
            }
        }
        if(isNotInSplitTypeMode) {
            if (isNeedCalcShipping) {
                List r = new ArrayList();
                r.add(calcAndCheckShippingQty);
                RedisUtils.set(RedisKeyConstants.SPLIT_ORDER_YSDWJC_TEMP_DATA + orderId, r);
            }
        }


        OrderSplitControlUtils.extendSupplyLgort(fullAtpDbrows);
        boolean hasOutCar = ctx.containsKey("hasOutCar");

        DaoUtils.copyListValues("productid", od, productInfo, "area");
        DaoUtils.copyListValues("productid", productInfo, od, "bucode");
        Map odmapByArea = DaoUtils.list2map(od, false, "area");
        Map fullAtpMap = DaoUtils.list2map(fullAtpDbrows, false, "productid");
        Map tm = OrderSplitControlUtils.odMap2gplist(odmapByArea, fullAtpMap);
        List gplist = (List) tm.get("gplist");
        List glist = (List) tm.get("glist");
        Map<String,Map> demands = DaoUtils.list2map(gplist, true, "productid");
        List finalSplitResult = new ArrayList();

        List fullAtpDbrows4nextdata = new ArrayList();
        fullAtpDbrows4nextdata.addAll(fullAtpDbrows);

        transunitQtyControls = isNotInSplitTypeMode?(transunitQtyControls==null||transunitQtyControls.size()<=0? (List<Map>) orderCheckService.checkPerCarQtyControl(orderId, calcAndCheckShippingQty).get("datas") : (List<Map>)transunitQtyControls.get(0).get("ret")):new ArrayList();
        //只要合计超出1车限制的
        List transunitQtyControlsAll = transunitQtyControls.stream().collect(Collectors.toList());
        transunitQtyControls = transunitQtyControls.stream().filter(r->(Boolean)r.get("isNeedSplitIntoCar")).collect(Collectors.toList());
        if(isNotInSplitTypeMode) {
            boolean isPass = isPass(calcAndCheckShippingQty);
            if (!isPass) {
                calcAndCheckShippingQty.put("errorMsg", "分单失败，吨位或系数不正确，请联系海天审单人员！");
                return calcAndCheckShippingQty;
            }
            if (calcAndCheckShippingQty.containsKey("isGZH")) {
                return DaoUtils.buildParamMap(
                        "pass", false
                        , "msg", "广中皇先不考虑自动分单"
                );
            }
        }
        String shippingno = isNotInSplitTypeMode?getStrFromMap(calcAndCheckShippingQty, "shippingno"): getStrFromMap(splitTypeData,"shippingNo");
        int shippingQtySp = isNotInSplitTypeMode?(int) getDecimalFromMap(calcAndCheckShippingQty, "shippingQtySp"): 1; //分车数量合并运输数量倍数
        shippingQtySp = shippingQtySp <= 0 ? 1 : shippingQtySp;
        Map bestRange = isNotInSplitTypeMode? (Map) calcAndCheckShippingQty.get("bestRange"):null;
        boolean splitZl = isNotInSplitTypeMode?"zl".equals(getStrFromMap(calcAndCheckShippingQty, "unit")) : true;
        double splitMin = isNotInSplitTypeMode?getDecimalFromMap(bestRange, "min"):1;
        double splitMax = isNotInSplitTypeMode?getDecimalFromMap(bestRange, "max"):1;
        double splitSpMin = isNotInSplitTypeMode?getDecimalFromMap(bestRange, "min"):1;
        double splitSpMax = isNotInSplitTypeMode?getDecimalFromMap(bestRange, "max"):1;
        double splitSpMinForLastCar = isNotInSplitTypeMode?getDecimalFromMap(bestRange, "spmin"):1;
        splitSpMinForLastCar = splitSpMinForLastCar<=0?splitSpMin:splitSpMinForLastCar;
        double splitSpMaxForLastCar = isNotInSplitTypeMode?getDecimalFromMap(bestRange, "spmax"):1;
        double xspmin = isNotInSplitTypeMode?getDecimalFromMap(calcAndCheckShippingQty, "xspmin"):0;//车皮用的2车合组时的检测范围
        double xspmax = isNotInSplitTypeMode?getDecimalFromMap(calcAndCheckShippingQty, "xspmax"):0;
        double ulimit = isNotInSplitTypeMode?getDecimalFromMap(bestRange, "ulimit"):0;//每一车不能超的体积或者重量
        double ulimitXs = isNotInSplitTypeMode?getDecimalFromMap(calcAndCheckShippingQty, "ulimitXs"):0;//特殊模式（水柜走汽运等）限制每车系数
        OrderSplitControlUtils.ulimitXsThreadLocal.set(ulimitXs);
        int splitShippingQty = isNotInSplitTypeMode?(int) getDecimalFromMap(calcAndCheckShippingQty, "splitShippingQty"):1;
        if (xspmin > 0) {
            splitMax = getDecimalFromMap(calcAndCheckShippingQty, "xmax") / shippingQtySp;
            splitSpMax = splitMax;
        }
        boolean isOldRdc = false;

        List<Map> loadPointCfgs = baseMapper.getLoadPointCfg(shippingno);

        OrderSplitControlUtils.extendProductInfo(productInfo, splitZl, splitMin, splitMax, ulimit);
        RedisUtils.set(RedisKeyConstants.SPLIT_ORDER_PRODUCTINFO_TEMP_DATA + orderId, productInfo);
        Map productMap = DaoUtils.list2map(productInfo, true, "productid");
        boolean isRdcX = KhUtil.isRdcOrder(orderMasterType);
        productMap.put("isRdcForCalcZyd",isRdcX);
        productMap.put("getCdTypeCfg",KhUtil.getCdTypeCfg());
        productMap.put("orderMasterType",orderMasterType);

        Map genMap = OrderSplitControlUtils.genSplitTask(glist, false);//nordc
        List splitSupplyList = (List) genMap.get("splitSupplyList");//此处的供应信息仅包含了ABC区指定仓库的部分
        List otherSupplyList = (List) genMap.get("otherSupplyList");
        List splitTask = (List) genMap.get("splitTask");

        Map supplysByProductid = DaoUtils.list2map(splitSupplyList, false, "productid");
        Map supplysByDateAndProductid = DaoUtils.list2map(splitSupplyList, false, "atpdate", "productid");
        Map supplysByLgortAndProductid = DaoUtils.list2map(splitSupplyList, false, LGORT_KEY, "productid");

        boolean hasPutAllAtpTogether = false;
        if (isNotInSplitTypeMode && calcAndCheckShippingQty.containsKey("shipModel")) {
            if(!isOldRdc && !hasPutAllAtpTogether) {
                //此处把其他产品加入到供应信息内
                splitSupplyList.addAll(otherSupplyList);
                supplysByProductid = DaoUtils.list2map(splitSupplyList, false, "productid");
                supplysByDateAndProductid = DaoUtils.list2map(splitSupplyList, false, "atpdate", "productid");
                supplysByLgortAndProductid = DaoUtils.list2map(splitSupplyList, false, LGORT_KEY, "productid");
                hasPutAllAtpTogether = true;
            }
            List shipModel = (List) calcAndCheckShippingQty.get("shipModel");
            OrderSplitControlUtils.splitByModel(shipModel, finalSplitResult, demands, supplysByDateAndProductid, supplysByLgortAndProductid, supplysByProductid, productMap);
            for (Map row : (List<Map>) finalSplitResult) {
                row.put("isByShipModel", true);
            }
        }



        Function<List<Map>,Map> getUlimitXsCar = (fsr)->{
            Map ret = new HashMap();
            if(ulimitXs>0) {
                Map notPassCar = fsr.stream().filter(
                        car -> {
                            return getDecimalFromMap(car, "restlimitsumxs") < 0;
                        }
                ).findFirst().orElse(null);
                if (null != notPassCar) {
                    ret.put("notPassCar", notPassCar);
                }
            }
            return ret;
        };

        BiFunction<Map,List<Map>,List<Map>> getTransunitQtyRuleInCar = (car,tsc)->{
            return tsc.stream().map(t->{
                int limit = (int)getDecimalFromMap(t,"limit");
                Map detailMap  = (Map)t.get("detailMap");
                int sum = ((List<Map>) car.get("details")).stream().mapToInt(r-> detailMap.containsKey(getStrFromMap(r,"productid"))?(int)getIntegerFromMap(r,"qty"):0 ).sum();
                return DaoUtils.buildParamMap("sum",sum, "pass",sum<=limit, "t",t, "limit",limit);
            }).filter(r->getIntegerFromMap(r,"sum")>0).collect(Collectors.toList());
        };
        BiFunction<List<Map>,List<Map>,Map> getTransunitQtyFailCar = (fsr,tsc)->{
            Map ret = new HashMap();
            Map notPassCar = fsr.stream().filter(
                    car->{
                        List<Map> rs = getTransunitQtyRuleInCar.apply(car, tsc);
                        boolean rpass = rs.stream().filter(r->!(Boolean)r.get("pass")).count()<=0;
                        if(!rpass){
                            ret.put("getTransunitQtyRuleInCar",rs);
                        }
                        return !rpass;
                    }
            ).findFirst().orElse(null);
            if(null!=notPassCar) {
                ret.put("notPassCar", notPassCar);
            }
            return ret;
        };
        List<Map> firstSplitCars = new ArrayList();
        if(!transunitQtyControls.isEmpty()){
            int spCarLeft = splitShippingQty-firstSplitCars.size()-finalSplitResult.size();
            if(!hasPutAllAtpTogether) {
                //此处把其他产品加入到供应信息内
                splitSupplyList.addAll(otherSupplyList);
                supplysByProductid = DaoUtils.list2map(splitSupplyList, false, "productid");
                supplysByDateAndProductid = DaoUtils.list2map(splitSupplyList, false, "atpdate", "productid");
                supplysByLgortAndProductid = DaoUtils.list2map(splitSupplyList, false, LGORT_KEY, "productid");
                hasPutAllAtpTogether = true;
            }
            List tdemands = new ArrayList();
            transunitQtyControls.stream().forEach(r->{
                ((Map)r.get("detailMap")).keySet().forEach(k->tdemands.add(DaoUtils.buildParamMap("productid",k,"sqty",getIntegerFromMap((Map)demands.get(k),"sqty"))));
            });
            List<Map> fdemands = ((Map<String,List<Map>>)DaoUtils.list2map(tdemands,false,"productid")).entrySet().stream()
                    .map(
                            e->DaoUtils.buildParamMap("productid",e.getKey(),"sqty",e.getValue().stream().mapToInt(r->getIntegerFromMap(r,"sqty")).sum())
                    ).collect(Collectors.toList());
            Map fdmap = DaoUtils.list2map(fdemands, true, "productid");
            List<List<Map>> carDemands = new ArrayList();

            Map xproductMap = productMap;
            for(int i=0;i<spCarLeft;i++) {//现装散的,后续装整板
                int xi = i;
                List<Map> xfdemands = (List)JSON.parseArray(JSON.toJSONString(fdemands));
                transunitQtyControls.stream().forEach(r -> {
                    int tlimit = getIntegerFromMap(r,"limit");
                    int qtypercar = (int)Math.ceil(getIntegerFromMap(r,"sum")/spCarLeft);
                    int qtypercarLeft = tlimit-qtypercar;
                    Map tmap = DaoUtils.buildParamMap("limit",tlimit,"xsum",getIntegerFromMap(r,"sum"));
                    Map detailMap = (Map) r.get("detailMap");
                    sortList(xfdemands,"sqty",false);
                    xfdemands.stream().forEach(fr -> {
                        if (detailMap.containsKey(getStrFromMap(fr, "productid"))) {
                            int pallet = getIntegerFromMap((Map)xproductMap.get(getStrFromMap(fr, "productid")), "pallet");
                            int pqty = getIntegerFromMap(fr, "sqty");
                            int limit = getIntegerFromMap(tmap, "limit");
                            int spqty = Math.min(limit, pqty);
                            int pspqty = (int)Math.floor(spqty/pallet)*pallet;//spqty>=pspqty
                            boolean isSplitPallet = pspqty<spqty;
                            boolean isEnough = qtypercarLeft>=limit;
                            boolean isBad = isSplitPallet && !isEnough;
                            int fspqty = isBad?spqty:pspqty;
                            fspqty = pspqty<=0?spqty:pspqty;
                            fspqty = xi==(spCarLeft-1)?spqty:fspqty;
                            if(detailMap.size()<=1) {
                                int frest = getIntegerFromMap(tmap, "xsum") - fspqty;
                                boolean xpass = frest <= tlimit * (spCarLeft - 1 - xi);
                                fspqty = xpass ? fspqty : spqty;
                            }
                            fr.put("sqty", fspqty);
                            tmap.put("xsum",getIntegerFromMap(tmap,"xsum")-fspqty);
                            limit-=fspqty;
                            if (limit < 0) {
                                tmap.put("limit",0);
                            }
                            else {
                                tmap.put("limit",limit);
                            }
                        }
                    });
                });
                List<Map> carDemand = xfdemands.stream().filter(r -> getIntegerFromMap(r, "sqty") > 0).collect(Collectors.toList());
                carDemand.forEach(r -> {
                    Map m = (Map) fdmap.get(getStrFromMap(r, "productid"));
                    int nsqty = getIntegerFromMap(m, "sqty") - getIntegerFromMap(r, "sqty");
                    m.put("sqty", nsqty);
                });
                carDemands.add(carDemand);
                buildcarsWithModel(firstSplitCars, demands, supplysByDateAndProductid
                        , supplysByLgortAndProductid, supplysByProductid, carDemand.stream().collect(Collectors.toMap(r->getStrFromMap(r,"productid"), r->getIntegerFromMap(r,"sqty")))
                        ,productMap, 1);
                int sumqty = fdemands.stream().mapToInt(r->getIntegerFromMap(r,"sqty")).sum();
                if(sumqty<=0){
                    break;
                }
            }

            OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(firstSplitCars,productMap,splitZl,splitSpMin,splitSpMax,ulimit);
        }
        firstSplitCars.forEach(r->{
            ((List<Map>)r.get("details")).forEach(rx->{
                rx.put("isFirstSplit",true);
            });
        });
        List<Map> outCars = ctx.containsKey("finalSplitResult")?(List)ctx.get("finalSplitResult"):new ArrayList();
        int spCarLeft = splitShippingQty-firstSplitCars.size()-finalSplitResult.size()-outCars.size();
        if(!outCars.isEmpty()) {
            if (spCarLeft < 0) {
                int exsize = Math.min(firstSplitCars.size(),Math.min(outCars.size(),Math.abs(spCarLeft)));
                OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(firstSplitCars,productMap,splitZl,splitSpMin,splitSpMax,ulimit);
                outCars = outCars.stream().sorted(Comparator.comparing(r -> getDecimalFromMap(r, "restspsum"))).collect(Collectors.toList());
                firstSplitCars = firstSplitCars.stream().sorted(Comparator.comparing(r -> getDecimalFromMap(r, "restsum"))).collect(Collectors.toList());
                for (int i = 0; i < exsize; i++) {
                    //merge car
                    Map a = firstSplitCars.get(i);
                    Map b = outCars.get(i);
                    a.put("planDate",Stream.of(getStrFromMap(a,"planDate"),getStrFromMap(b,"planDate")).sorted(Comparator.reverseOrder()).findFirst().get());
                    ((List)a.get("details")).addAll((List)b.get("details"));
                    a.put("isOutCar",true);
                }
                for(int i=exsize;i<outCars.size();i++){
                    firstSplitCars.add(outCars.get(i));
                }
            }
            else {
                firstSplitCars.addAll(outCars);
            }
        }
        spCarLeft = splitShippingQty-firstSplitCars.size()-finalSplitResult.size();
        spCarLeft=spCarLeft<0?0:spCarLeft;
        boolean isNoSpCarLeft = spCarLeft<=0;
        boolean isOnly1car = !isNotInSplitTypeMode || splitShippingQty<=1;//某些运输方式只下了一车的情况，直接跳过前4轮分车，避免分车数量超了
        List<Map> finalSplitResultRest = new ArrayList();
        List<Map> tmpOutCars = firstSplitCars.stream().filter(r->r.containsKey("isOutCar")).collect(Collectors.toList());;
        firstSplitCars = firstSplitCars.stream().filter(r->!r.containsKey("isOutCar")).collect(Collectors.toList());

        //特殊产品装车思路：先算出特殊产品会分到多少车，控制整车单区单产品单仓库分车数量，后续作为默认车开始分

        //整车单区单产品单仓库，处理共有产品取日期更优的仓
        List splitResult1 = isOnly1car||isNoSpCarLeft?null:OrderSplitControlUtils.splitByAreaRange1(finalSplitResultRest,demands,supplysByDateAndProductid,supplysByLgortAndProductid,productMap,splitTask,spCarLeft);
        //整车单区多产品单仓库
        List splitResult2 = isOnly1car?null:OrderSplitControlUtils.splitByAreaRange2(finalSplitResultRest,firstSplitCars,demands,supplysByDateAndProductid,supplysByLgortAndProductid,productMap,splitTask, splitZl, splitMin, splitMax, ulimit,spCarLeft-finalSplitResultRest.size());

        if(!hasPutAllAtpTogether) {
            //此处把其他产品加入到供应信息内
            splitSupplyList.addAll(otherSupplyList);
            supplysByProductid = DaoUtils.list2map(splitSupplyList, false, "productid");
            supplysByDateAndProductid = DaoUtils.list2map(splitSupplyList, false, "atpdate", "productid");
            supplysByLgortAndProductid = DaoUtils.list2map(splitSupplyList, false, LGORT_KEY, "productid");
        }
        //整车多区多产品单仓库，优先减少调拨
        List splitResult22 = isOnly1car?null:OrderSplitControlUtils.splitByAreaRange22(finalSplitResultRest,firstSplitCars,demands,supplysByDateAndProductid,supplysByLgortAndProductid,productMap
                ,splitTask, splitZl, splitMin, splitMax,splitSpMin,splitSpMax, ulimit,spCarLeft-finalSplitResultRest.size());
        if(spCarLeft-finalSplitResultRest.size()>0){
            boolean isFixOneCar = true;
            List splitResult222 = isOnly1car?null:OrderSplitControlUtils.splitByAreaRange22(finalSplitResultRest,firstSplitCars,demands,supplysByDateAndProductid,supplysByLgortAndProductid,productMap
                    ,splitTask, splitZl, splitMin, splitMax,splitSpMin,splitSpMax, ulimit,spCarLeft-finalSplitResultRest.size(),isFixOneCar);
            if(splitResult222!=null){
                //log.info("splitResult222:{}",splitResult222);
            }
        }

        //整车单区多产品多仓库
        //List splitResult3 = OrderSplitControlUtils.splitByAreaRange3(finalSplitResultRest,demands,supplysByDateAndProductid,supplysByLgortAndProductid,productMap,splitTask, splitZl, splitMin, splitMax, ulimit);

        //gen better lgort
        //OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(finalSplitResultRest,productMap,splitZl,splitSpMin,splitSpMax,ulimit);
        //List<String> betterLgorts = (List)finalSplitResultRest.stream().filter(r -> ((List) ((Map) r).get("lgortDetails")).size() == 1).sorted(Comparator.comparing(r -> getDecimalFromMap((Map) r, "restsum")))
        //        .map(r -> getStrFromMap(((List<Map>) ((Map) r).get("lgortDetails")).get(0), LGORT_KEY)).collect(Collectors.toList());

        //所有产品混装
        List splitResult4 = isOnly1car?null:OrderSplitControlUtils.splitByAreaRange4(finalSplitResultRest,firstSplitCars,demands,supplysByDateAndProductid,supplysByLgortAndProductid,productMap
                ,splitTask, splitZl, splitMin, splitMax,splitSpMin,splitSpMax, ulimit,spCarLeft-finalSplitResultRest.size());
        int sp = splitZl?1000:1;
        List msgs = new ArrayList();
        log.info("orderId:{} msg:{}",orderId,String.format("当前订单运输方式%s%s%s，使用%s范围%s-%s，最大范围%s-%s，额外限制%s%s，吨位检测运输数量为%.2f"
                ,shippingno
                ,calcAndCheckShippingQty.containsKey("shipModel")?((isOldRdc?"，RDC装车数量":"，整柜数量")+getDecimalFromMap(calcAndCheckShippingQty,"justRightQty")):""
                ,loadPointCfgs.size()>0?"，多区装运配置"+getStrFromMap((Map)loadPointCfgs.get(0),"name"):""
                ,splitZl?"重量":"系数"
                ,splitMin/sp,splitMax/sp
                ,splitSpMin/sp,splitSpMax/sp
                ,splitZl?"体积":"重量",ulimit
                ,getDecimalFromMap(calcAndCheckShippingQty,"shippingQty")));

        firstSplitCars.addAll(tmpOutCars);
        if(!firstSplitCars.isEmpty()){
            finalSplitResultRest.addAll(firstSplitCars);
            firstSplitCars.clear();
        }
//        /*非最后一车，不浮动*/ //不过这种也有一个办法，就是现在一张订单只允许一车有浮动的，可以放大到二车有浮动
//        int floatCount = 2;
//        for(int i=0,len=finalSplitResultRest.size();i<(len-floatCount+1);i++) {
//            Object row = finalSplitResultRest.get(i);
//            ((Map)row).put("xsplitSpMin",splitSpMin);
//            ((Map)row).put("xsplitSpMax",splitSpMax);
//            ((Map)row).put("xulimit",ulimit);
//        }
        OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(finalSplitResultRest,productMap,splitZl,splitSpMin,splitSpMax,ulimit);

        Map restProducts = OrderSplitControlUtils.calcRest(gplist,msgs,productMap,splitZl,splitSpMinForLastCar,splitSpMaxForLastCar,false,"sqty",isNotInSplitTypeMode);
        List tpdetails = (List) restProducts.get("details");
        if(tpdetails.size()>0 && hasOutCar) {//外仓车先塞满
            sortList(tpdetails, "sum", false);

            List<Map> tfinalSplitResultRest = ((List<Map>) finalSplitResultRest).stream().filter(rx -> !(rx.containsKey("isByShipModel") || rx.containsKey("isByUlimit"))).collect(Collectors.toList());
            if (tfinalSplitResultRest.size() > 0) {

                sortList(tfinalSplitResultRest, "sum", true);
                OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(tfinalSplitResultRest, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
                Map tpdemands = DaoUtils.list2map(tpdetails, true, "productid");

                OrderSplitControlUtils.extendProductInfo(productInfo, splitZl, splitMin, splitMax, ulimit);
                productMap = DaoUtils.list2map(productInfo, true, "productid");
                productMap.put("isRdcForCalcZyd",isRdcX);
                productMap.put("getCdTypeCfg",KhUtil.getCdTypeCfg());
                productMap.put("orderMasterType",orderMasterType);

                //剩余一堆不够一车的散货填装到其他车的处理顺序
                //整板堆到其他有相同仓库的车,不改车发运日期
                OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(tfinalSplitResultRest, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
                List s1 = OrderSplitControlUtils.splitLastInPalletAndLgort(tpdetails, productMap, splitZl, tfinalSplitResultRest, supplysByProductid, supplysByLgortAndProductid);
                //可非整板堆到其他有相同仓库的车,不改车发运日期
                OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(tfinalSplitResultRest, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
                List s2 = OrderSplitControlUtils.splitLastInLgort(tpdetails, productMap, splitZl, tfinalSplitResultRest, supplysByProductid, supplysByLgortAndProductid);
                //可非整板堆到其他无相同仓库的车,不改车发运日期
                OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(tfinalSplitResultRest, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
                List s3 = OrderSplitControlUtils.splitLastInSamePlanDateOnly(tpdetails, productMap, splitZl, tfinalSplitResultRest, supplysByProductid, supplysByLgortAndProductid);
                //可非整板堆到其他无相同仓库的车,可改车发运日期
                OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(tfinalSplitResultRest, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
                List s4 = OrderSplitControlUtils.splitLastNoSplitOnly(tpdetails, productMap, splitZl, tfinalSplitResultRest, supplysByProductid, supplysByLgortAndProductid);

                sortList(tfinalSplitResultRest, "carseq", true);
            }

            OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(finalSplitResultRest, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
            restProducts = OrderSplitControlUtils.calcRest(tpdetails, msgs, productMap, splitZl, splitSpMin, splitSpMax, false, "qty");
            tpdetails = (List) restProducts.get("details");
        }

//        restProducts = OrderSplitControlUtils.calcRest(gplist,msgs,productMap,splitZl,splitSpMinForLastCar,splitSpMaxForLastCar,false,"sqty",isNotInSplitTypeMode);
//        tpdetails = (List) restProducts.get("details");
        boolean isShippingQtyPass = isPass(restProducts) || getDecimalFromMap(restProducts,"shippingQty")>1;
        boolean isLastByUlimit = false;
        if(!isShippingQtyPass && isNotInSplitTypeMode && calcAndCheckShippingQty.containsKey("isAutoReduce") && (Boolean)calcAndCheckShippingQty.get("isAutoReduce") && (splitShippingQty-finalSplitResultRest.size())>0){
            Map sret = ShippingQtyControlUtils.isPassUlimit(splitShippingQty-finalSplitResultRest.size(), ulimit,getDecimalFromMap(restProducts,"tlimitsum"),ulimitXs,getDecimalFromMap(restProducts,"tlimitsumxs"));
            if(isPass(sret)){
                restProducts.put("shippingQty",splitShippingQty-finalSplitResultRest.size());
                isShippingQtyPass = true;
                isLastByUlimit = true;
            }
        }
        boolean pass = isShippingQtyPass;
        boolean hasRest = false;
        boolean hasUlimitPass = false;
        int restCarCount = (splitShippingQty-finalSplitResultRest.size()-finalSplitResult.size());
        if(pass && firstSplitCars.isEmpty() && restCarCount>0) {
            if(tpdetails.size()>0) {
                int shippingQty = Math.min((int)getDecimalFromMap(restProducts,"shippingQty"),restCarCount);
                for(int i=0;i<shippingQty;i++){
                    splitSpMin = splitSpMinForLastCar;
                    splitSpMax = splitSpMaxForLastCar;
                    Map fmap = new HashMap();
                    for(Object row: tpdetails) {
                        Map mrow = (Map)row;
                        if(supplysByProductid.containsKey(mrow.get("productid"))){
                            fmap.put(mrow.get("productid"),mrow.get("qty"));
                        }
                    }
                    if(fmap.isEmpty()){
                        continue;
                    }
                    List<Map> tfinalSplitResultRest = new ArrayList();
                    OrderSplitControlUtils.buildcarsWithModelWtihFlagAndUlimit(tfinalSplitResultRest,demands,supplysByDateAndProductid,supplysByLgortAndProductid,supplysByProductid,fmap,productMap,1,true,ulimit
                            ,splitZl,splitSpMinForLastCar,splitSpMaxForLastCar,isNotInSplitTypeMode
                    );
                    if(isLastByUlimit){
                        OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(tfinalSplitResultRest,productMap,splitZl,splitSpMin,splitSpMax,ulimit);
                        for (Object row : tfinalSplitResultRest) {
                            Map car = (Map) row;
                            if (car.containsKey("isByShipModel") || car.containsKey("isByUlimit")) {
                                continue;
                            }
                            boolean iscarok = getDecimalFromMap(car, "restsum") >= 0 && getDecimalFromMap(car, "restspsum") >= 0;
                            if(!iscarok){
                                car.put("isByUlimit",true);
                            }
                        }
                    }
                    finalSplitResultRest.addAll(tfinalSplitResultRest);
                    OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(finalSplitResultRest,productMap,splitZl,splitSpMin,splitSpMax,ulimit);
                    restProducts = OrderSplitControlUtils.calcRest(gplist,msgs,productMap,splitZl,splitSpMin,splitSpMax,false,"sqty",isNotInSplitTypeMode);
                    tpdetails = (List) restProducts.get("details");
                    pass = isPass(restProducts);
                }
            }
        }
        if(splitShippingQty<= (finalSplitResultRest.size()+finalSplitResult.size()) || hasOutCar){
            if(tpdetails.size()>0) {
                if(!isNotInSplitTypeMode){
                    splitSpMax=9999999;
                    splitMax=9999999;
                    xspmax=9999999;
                    splitSpMaxForLastCar=9999999;
                }
                sortList(tpdetails, "sum", false);

                List<Map> tfinalSplitResultRest = ((List<Map>) finalSplitResultRest).stream().filter(rx -> !(rx.containsKey("isByShipModel") || rx.containsKey("isByUlimit"))).collect(Collectors.toList());
                if (tfinalSplitResultRest.size() > 0) {
                    int carseq = 0;
                    for (Map row : (List<Map>) finalSplitResultRest) {
                        row.put("carseq", carseq++);
                        row.put("xsplitSpMin", splitSpMin);
                        row.put("xsplitSpMax", splitSpMax);
                        row.put("xulimit", ulimit);
                    }
                    splitSpMin = splitSpMinForLastCar;
                    splitSpMax = splitSpMaxForLastCar;
                    sortList(tfinalSplitResultRest, "sum", true);
                    List xfinalSplitResult = new ArrayList();
                    if (tfinalSplitResultRest.size() > 0) {
                        Object row = tfinalSplitResultRest.get(0);//lastcar 改为取可浮动量最大的车
                        ((Map) row).put("xsplitSpMin", splitSpMin);
                        ((Map) row).put("xsplitSpMax", splitSpMax);
                        ((Map) row).put("xulimit", ulimit);
                        xfinalSplitResult.add(row);
                    }
                    if (tfinalSplitResultRest.size() > 1) {
                        Object row = tfinalSplitResultRest.get(1);//lastcar 改为取可浮动量最大的车
                        ((Map) row).put("xsplitSpMin", splitSpMin);
                        ((Map) row).put("xsplitSpMax", splitSpMax);
                        ((Map) row).put("xulimit", ulimit);
                        xfinalSplitResult.add(row);
                    }
                    OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(tfinalSplitResultRest, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
                    Map tpdemands = DaoUtils.list2map(tpdetails, true, "productid");
                    OrderSplitControlUtils.tryNoSplitPalletAftersplitByAreaRange4(xfinalSplitResult, supplysByLgortAndProductid, productMap, tpdemands, "qty", splitZl, splitSpMin, splitSpMax, ulimit);

                    double maxSum = tfinalSplitResultRest.stream().mapToDouble(r->getDecimalFromMap(r,"sum")).max().getAsDouble();
                    tfinalSplitResultRest.forEach(r->r.put("seqsum",r.containsKey("isOutCar")?(maxSum+getDecimalFromMap(r,"sum")):getDecimalFromMap(r,"sum")));
                    sortList(tfinalSplitResultRest, "seqsum", false);

                    OrderSplitControlUtils.extendProductInfo(productInfo, splitZl, splitMin, splitMax, ulimit);
                    productMap = DaoUtils.list2map(productInfo, true, "productid");
                    productMap.put("isRdcForCalcZyd",isRdcX);
                    productMap.put("getCdTypeCfg",KhUtil.getCdTypeCfg());
                    productMap.put("orderMasterType",orderMasterType);

                    //剩余一堆不够一车的散货填装到其他车的处理顺序
                    //整板堆到其他有相同仓库的车,不改车发运日期
                    OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(tfinalSplitResultRest, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
                    List s1 = OrderSplitControlUtils.splitLastInPalletAndLgort(tpdetails, productMap, splitZl, tfinalSplitResultRest, supplysByProductid, supplysByLgortAndProductid);
                    //可非整板堆到其他有相同仓库的车,不改车发运日期
                    OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(tfinalSplitResultRest, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
                    List s2 = OrderSplitControlUtils.splitLastInLgort(tpdetails, productMap, splitZl, tfinalSplitResultRest, supplysByProductid, supplysByLgortAndProductid);
                    //可非整板堆到其他无相同仓库的车,不改车发运日期
                    OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(tfinalSplitResultRest, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
                    List s3 = OrderSplitControlUtils.splitLastInSamePlanDateOnly(tpdetails, productMap, splitZl, tfinalSplitResultRest, supplysByProductid, supplysByLgortAndProductid);
                    //可非整板堆到其他无相同仓库的车,可改车发运日期
                    OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(tfinalSplitResultRest, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
                    List s4 = OrderSplitControlUtils.splitLastNoSplitOnly(tpdetails, productMap, splitZl, tfinalSplitResultRest, supplysByProductid, supplysByLgortAndProductid);

                    sortList(tfinalSplitResultRest, "carseq", true);
                }

                OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(finalSplitResultRest, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
                restProducts = OrderSplitControlUtils.calcRest(tpdetails, msgs, productMap, splitZl, splitSpMin, splitSpMax, false, "qty");
                tpdetails = (List) restProducts.get("details");
                pass = isPass(restProducts);
                hasRest = !pass;
                if(!pass){
                    hasUlimitPass = (
                            finalSplitResultRest.stream().filter(r->r.containsKey("isByUlimit") && (Boolean)r.get("isByUlimit")).findFirst().isPresent()
                                    && 1000>=getIntegerFromMap(restProducts,"sumzl")
                    );
                    pass = hasUlimitPass;
                }
            }
        }
        else {// if(spShippingQty>finalSplitResult.size()){
            Map fmap = new HashMap();
            for(Object row: tpdetails) {
                Map mrow = (Map)row;
                fmap.put(mrow.get("productid"),mrow.get("qty"));
            }
            List tfinalSplitResult = new ArrayList();
            buildcarsWithModel(tfinalSplitResult,demands,supplysByDateAndProductid,supplysByLgortAndProductid,supplysByProductid,fmap,productMap,1);
            finalSplitResultRest.addAll(tfinalSplitResult);
            OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(finalSplitResultRest,productMap,splitZl,splitSpMin,splitSpMax,ulimit);
            int currentCarIdx = finalSplitResultRest.size()-1;
            boolean isDone = false;
            while(!isDone && currentCarIdx>=1) {
                isDone = OrderSplitControlUtils.fetchIntoCar(currentCarIdx,finalSplitResultRest,productMap,splitZl);
                OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(finalSplitResultRest,productMap,splitZl,splitSpMin,splitSpMax,ulimit);
                currentCarIdx--;
            }
            pass = isDone;
            restProducts.put("pass",pass);
            if(pass) {
                tpdetails.clear();
            }
        }

        for(Object row: finalSplitResult) {
            ((Map)row).put("shippingNo",shippingno);
        }
        for(Object row: finalSplitResultRest) {
            ((Map)row).put("shippingNo",shippingno);
        }

        boolean enableBetterShareLgort = true;//共有产品优化分在产品吨位多的区域，减少调拨
        if(enableBetterShareLgort) {
            OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(finalSplitResultRest, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
            boolean isAllRestCarOk = true;//除rdc仓以外的车
            if(isNotInSplitTypeMode) {
                for (Object row : finalSplitResultRest) {
                    Map car = (Map) row;
                    if (car.containsKey("isByShipModel") || car.containsKey("isByUlimit")) {
                        continue;
                    }
                    isAllRestCarOk = isAllRestCarOk && getDecimalFromMap(car, "restsum") >= 0 && getDecimalFromMap(car, "restspsum") >= 0;
                }
            }
            if (isAllRestCarOk) {
                for (Map car : finalSplitResultRest) {//遍历车
                    String planDate = getStrFromMap(car,"planDate");
                    List details = (List) car.get("details");
                    List lgortDetails = (List) car.get("lgortDetails");
                    if(lgortDetails.size()>1) {//多仓才优化
                        Map dmap = DaoUtils.list2map(details,false,LGORT_KEY);
                        Map lmap = DaoUtils.list2map(lgortDetails,true,LGORT_KEY);
                        sortList(lgortDetails, "sumzl", true);//仓库排序,从小到大
                        for (Map lgortRow : (List<Map>) lgortDetails) {//遍历仓库,尝试把小仓的产品调到共有的大仓
                            String lgort = getStrFromMap(lgortRow,LGORT_KEY);
                            List ldlist = (List)dmap.get(lgort);
                            for(Map mrow: (List<Map>)ldlist){//遍历小仓的所有产品
                                String mlgort = getStrFromMap(mrow, LGORT_KEY);
                                String productid = getStrFromMap(mrow, "productid");
                                Map productRow = (Map)productMap.get(getStrFromMap(mrow,"productid"));
                                int qty = (int)getDecimalFromMap(mrow, "qty");
                                double pzl = getDecimalFromMap(productRow,"dwzl")*qty;
                                String shareLgort = OrderSplitControlUtils.getShareLgort(
                                        getStrFromMap(productRow,"area")
                                        ,mlgort);
                                boolean isshareLgortExist = null!=shareLgort && dmap.containsKey(shareLgort)
                                        && getDecimalFromMap((Map)lmap.get(shareLgort),"sumzl")>=getDecimalFromMap((Map)lmap.get(mlgort),"sumzl");
                                if(isshareLgortExist){//存在共有仓库,并且当前车也有共有仓库的产品,并且共有仓库的重量不小于当前仓
                                    List shareSupply = (List) supplysByLgortAndProductid.get(DaoUtils.getValuesStr(shareLgort,productid));
                                    if(null!=shareSupply){
                                        Map atpRow = (Map)DaoUtils.list2map(shareSupply,true,"atpdate").get(planDate);
                                        int atp = (int)getDecimalFromMap(atpRow,"atp");
                                        if(atp>=qty) {
                                            //优化成功,增加共有仓的统计重量,减少当前仓统计重量
                                            OrderSplitControlUtils.reduceSupply(supplysByLgortAndProductid,productid,shareLgort,qty,atp-qty);
                                            OrderSplitControlUtils.reduceSupply(supplysByLgortAndProductid,productid,lgort,0-qty,-1,planDate);
                                            ((Map)lmap.get(shareLgort)).put("sumzl",getDecimalFromMap((Map)lmap.get(shareLgort),"sumzl")+pzl);
                                            ((Map)lmap.get(lgort)).put("sumzl",getDecimalFromMap((Map)lmap.get(lgort),"sumzl")-pzl);
                                            mrow.put(LGORT_KEY,shareLgort);
                                            log.info("BetterShareLgort-{}-{}-{}-{}",productid,lgort,shareLgort,qty);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(finalSplitResultRest, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
                if(hasRest){//回插产品时，有可能超重量或系数插不进去，这时候就开始减机动产品，按整板数量减
                    Set flexSet = new HashSet();
                    for(Map row: od){
                        if(StringUtils.equalsAny(getStrFromMap(row,"flexproduct"),"1","true")){
                            flexSet.add(getStrFromMap(row,"productid"));
                        }
                    }
                    Map tpmap = DaoUtils.list2map(tpdetails,true,"productid");
                    List tplglist = new ArrayList();
                    for(Map row: (List<Map>)tpdetails){
                        Object pid = row.get("productid");
                        if(!supplysByProductid.containsKey(pid)){
                            continue;
                        }
                        Set lset = new HashSet();
                        for(Map lgrow: (List<Map>)supplysByProductid.get(pid)){
                            lset.add(lgrow.get(LGORT_KEY));
                        }
                        for(Object lg: lset){
                            tplglist.add(DaoUtils.buildParamMap("productid",pid,LGORT_KEY,lg
                                    ,"qty",row.get("qty")
                            ));
                        }
                    }
                    Map tplgmap = DaoUtils.list2map(tplglist,false,LGORT_KEY);
                    for (Map car : (List<Map>) finalSplitResultRest) {//遍历车
                        List lgortDetails = (List) car.get("lgortDetails");
                        Map lmap = DaoUtils.list2map(lgortDetails,true,LGORT_KEY);
                        List details = (List) car.get("details");
                        Map dmap = DaoUtils.list2map(details,false,"productid");
                        boolean containsFlexProduct = false;
                        Object fp = "";
                        for(Object pid: flexSet){
                            containsFlexProduct = containsFlexProduct || dmap.containsKey(pid);
                            if(containsFlexProduct) {
                                fp = dmap.get(pid);
                                break;
                            }
                        }
                        boolean containsTpLgort = false;
                        Object tp = "";
                        for(Object tplgkey: tplgmap.keySet()){
                            containsTpLgort = containsTpLgort || lmap.containsKey(tplgkey);
                            if(containsTpLgort) {
                                tp = tplgmap.get(tplgkey);
                                break;
                            }
                        }
                        if(containsFlexProduct && containsTpLgort) {
                            log.info("BetterShareLgortFlex-{}-{}", fp ,tp);
                        }
                    }
                }
                //回插end
            }
        }

        finalSplitResult.addAll(finalSplitResultRest);
        if(hasOutCar && finalSplitResult.isEmpty()){
            Map splitMap = new HashMap();
            Map outAtpMap = supplysByProductid;
            demands.entrySet().stream().filter(e->outAtpMap.containsKey(e.getKey())).forEach(e->splitMap.put(e.getKey(),getIntegerFromMap(e.getValue(),"sqty")));
            List tfinalSplitResult = new ArrayList();
            buildcarsWithModel(tfinalSplitResult, demands, supplysByDateAndProductid
                    , supplysByLgortAndProductid, supplysByProductid, splitMap, productMap, 1);
            tfinalSplitResult.forEach(row->((Map)row).put("shippingNo",shippingno));
            finalSplitResult.addAll(tfinalSplitResult);
        }
        if(finalSplitResult.size()>splitShippingQty){
            return DaoUtils.buildParamMap(
                    "pass", false
                    , "msg", "分车数量计算错误，请联系管理员"
                    , "restProducts", restProducts
                    , "productInfo", productInfo
                    //, "calcAndCheckShippingQty", calcAndCheckShippingQty
                    , "finalSplitResult", finalSplitResult
            );
        }
        OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(finalSplitResult, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
        //07、10车吨位调平
        boolean isSpShippingno = "07,10".contains(shippingno);
        if(isSpShippingno && finalSplitResult.size()>1){
            int splimit = 3000;//3吨
            sortList(finalSplitResult, "limitsum", false);
            Map xbig = (Map)finalSplitResult.get(0);
            Map xsmall = (Map)finalSplitResult.get(finalSplitResult.size()-1);
            double xspzl = getDecimalFromMap(xbig,"limitsum")
                    - getDecimalFromMap(xsmall,"limitsum");
            boolean isSp = xspzl>splimit;
            if(isSp){
                for(int i=0,len=finalSplitResult.size();i<len;i++){
                    ((Map)finalSplitResult.get(i)).put("carid",i);
                }
                List<Map> rets = new ArrayList();
                boolean xpass = false;
                List nfinalSplitResult = JSON.parseArray(JSON.toJSONString(finalSplitResult));
                for(int times=0,len=nfinalSplitResult.size();times<len;times++) {
                    Map big = (Map) nfinalSplitResult.get(0);
                    Map small = (Map) nfinalSplitResult.get(nfinalSplitResult.size() - 1);
                    double spzl = getDecimalFromMap(big, "limitsum")
                            - getDecimalFromMap(small, "limitsum");
                    //寻找合适的一板产品
                    Map bmap = DaoUtils.list2map((List<Map>) big.get("details"), true, "productid");
                    Map nproductMap = new HashMap(productMap);
                    Map ret = new HashMap();
                    ((List<Map>) big.get("details")).stream().filter(b2sprodrow -> {
                        Map bprodrow = (Map) nproductMap.get(b2sprodrow.get("productid"));
                        double bpalletdwzl = getDecimalFromMap(bprodrow, "palletdwzl");
                        double bpalletdwxs = getDecimalFromMap(bprodrow, "palletdwxs");
                        ((List<Map>) small.get("details")).stream().filter(s2bprodrow -> {
                            Map sprodrow = (Map) nproductMap.get(s2bprodrow.get("productid"));
                            double spalletdwzl = getDecimalFromMap(sprodrow, "palletdwzl");
                            double spalletdwxs = getDecimalFromMap(sprodrow, "palletdwxs");
                            Map omr = IntStream.range(0, (int) (getIntegerFromMap(b2sprodrow, "qty") / getIntegerFromMap(bprodrow, "pallet"))).mapToObj(b -> {
                                int fi = IntStream.range(0, (int) (getIntegerFromMap(s2bprodrow, "qty") / getIntegerFromMap(sprodrow, "pallet"))).filter(s -> {
                                    double changexs = b * bpalletdwxs - s * spalletdwxs;
                                    double changezl = b * bpalletdwzl - s * spalletdwzl;
                                    boolean isSpOk = splimit >= (spzl - changezl * 2);
                                    boolean isSmallOk = changexs > 0 ? changexs <= getDecimalFromMap(small, "restsum") : Math.abs(changexs) <= getDecimalFromMap(small, "restspsum");
                                    boolean isBigOk = changexs < 0 ? Math.abs(changexs) <= getDecimalFromMap(big, "restsum") : changexs <= getDecimalFromMap(big, "restspsum");
                                    return isSpOk && isSmallOk && isBigOk;
                                }).findFirst().orElse(-1);
                                return DaoUtils.buildParamMap("b", b, "s", fi);
                            }).filter(mr -> {
                                return getIntegerFromMap(mr, "b") >= 0 && getIntegerFromMap(mr, "s") >= 0;
                            }).findFirst().orElse(null);
                            boolean isPass = omr != null;
                            if (isPass) {
                                omr.put("b2sprodrow", b2sprodrow);
                                omr.put("s2bprodrow", s2bprodrow);
                                omr.put("bigid", big.get("carid"));
                                omr.put("smallid", small.get("carid"));
                                ret.putAll(omr);
                            }
                            return isPass;
                        }).findFirst();
                        return !ret.isEmpty();
                    }).findFirst();
                    log.info("tryfix0710-{}-times{}-{}", orderId,times, ret);
                    if (!ret.isEmpty()) {
                        rets.add(ret);
                        Map b2sprodrow = (Map) ret.get("b2sprodrow");
                        Map bprodrow = (Map) nproductMap.get(b2sprodrow.get("productid"));
                        Map bnrow = new HashMap(b2sprodrow);
                        int b2sqty = (int) (getIntegerFromMap(ret,"b") * getIntegerFromMap(bprodrow, "pallet"));
                        b2sprodrow.put("qty", getIntegerFromMap(b2sprodrow, "qty") - b2sqty);
                        bnrow.put("qty", b2sqty);
                        ((List) small.get("details")).add(bnrow);

                        Map s2bprodrow = (Map) ret.get("s2bprodrow");
                        Map sprodrow = (Map) nproductMap.get(s2bprodrow.get("productid"));
                        Map snrow = new HashMap(s2bprodrow);
                        int s2bqty = (int) (getIntegerFromMap(ret,"s") * getIntegerFromMap(sprodrow, "pallet"));
                        s2bprodrow.put("qty", getIntegerFromMap(s2bprodrow, "qty") - s2bqty);
                        snrow.put("qty", s2bqty);
                        ((List) big.get("details")).add(snrow);
                        //big-->small   sync plandate
                        List<Map> b2sl = (List<Map>) supplysByLgortAndProductid.get(DaoUtils.getValuesStr(b2sprodrow, LGORT_KEY, "productid"));
                        List<Map> s2bl = (List<Map>) supplysByLgortAndProductid.get(DaoUtils.getValuesStr(s2bprodrow, LGORT_KEY, "productid"));
                        String b2spdate = getStrFromMap(b2sl.get(b2sl.size()-1),"atpdate");
                        String s2bpdate = getStrFromMap(s2bl.get(s2bl.size()-1),"atpdate");
//                        int cp = DateUtils.compare(getStrFromMap(small, "planDate"), getStrFromMap(big, "planDate"));
//                        int cpb = DateUtils.compare(spdate, getStrFromMap(big, "planDate"));
//                        int cps = DateUtils.compare(bpdate, getStrFromMap(small, "planDate"));
//                        if (cp > 0) {//small>big  set big=small
//                            big.put("planDate", getStrFromMap(small, "planDate"));
//                        } else {
//                            small.put("planDate", getStrFromMap(big, "planDate"));
//                        }
                        big.put("planDate", Arrays.asList(Arrays.asList(new String[]{getStrFromMap(small, "planDate"),s2bpdate  }).stream().sorted().collect(Collectors.toList()).get(0)
                                ,getStrFromMap(big, "planDate")).stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).get(0)
                        );
                        small.put("planDate", Arrays.asList(Arrays.asList(new String[]{getStrFromMap(big, "planDate"),b2spdate  }).stream().sorted().collect(Collectors.toList()).get(0)
                                ,getStrFromMap(small, "planDate")).stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).get(0)
                        );
                        OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(nfinalSplitResult, productMap, splitZl, splitSpMin, splitSpMax, ulimit);
                        sortList(nfinalSplitResult, "limitsum", false);
                        Map cbig = (Map)nfinalSplitResult.get(0);
                        Map csmall = (Map)nfinalSplitResult.get(nfinalSplitResult.size()-1);
                        double cspzl = getDecimalFromMap(cbig,"limitsum")
                                - getDecimalFromMap(csmall,"limitsum");
                        boolean isSpNow = cspzl>splimit;
                        if(!isSpNow){
                            Map rxx = getTransunitQtyFailCar.apply(nfinalSplitResult,transunitQtyControlsAll);
                            Map xsxx = getUlimitXsCar.apply(nfinalSplitResult);
                            if(rxx.isEmpty() && xsxx.isEmpty()) {
                                xpass = true;
                                break;
                            }
                            else {
                                log.info("getTransunitQtyFailCar fail in 07/10");
                                xpass=false;
                                break;
                            }
                        }
                    } else {
                        break;
                    }
                }

                if(xpass){
                    finalSplitResult = nfinalSplitResult;
                    daoBatchService.logFix0710(null,DaoUtils.buildParamMap("orderId",orderId,"rets",rets));
                }
                else {
                    daoBatchService.logFix0710("3E",DaoUtils.buildParamMap("orderId",orderId,"rets",rets));
                }
            }
        }

        boolean isAllCarOk = true;
        boolean isNeedAdd = false;
        if(isNotInSplitTypeMode) {
            for (Object row : finalSplitResult) {
                Map car = (Map) row;
                if (car.containsKey("isByShipModel") || car.containsKey("isByUlimit")) {
                    continue;
                }
                isAllCarOk = isAllCarOk && getDecimalFromMap(car, "restsum") >= 0 && getDecimalFromMap(car, "restspsum") >= 0;
                isNeedAdd = getDecimalFromMap(car, "restspsum") < 0 || isNeedAdd;
            }
        }
        if(!isAllCarOk && hasUlimitPass){
            isAllCarOk = hasUlimitPass;
        }
        pass = isAllCarOk;
        if(isAllCarOk) {
            Map rxx = getTransunitQtyFailCar.apply(finalSplitResult,transunitQtyControlsAll);
            if(!rxx.isEmpty()) {
                return DaoUtils.buildParamMap(
                        "pass", false
                        , "msg", "特殊产品分单计算错误，请联系管理员，相关运输限制数量："+getStrFromMap(((List<Map>)rxx.get("getTransunitQtyRuleInCar")).get(0),"limit")
                        , "restProducts", restProducts
                        , "productInfo", productInfo
                        //, "calcAndCheckShippingQty", calcAndCheckShippingQty
                        , "finalSplitResult", finalSplitResult
                );
            }
            Map xsxx = getUlimitXsCar.apply(finalSplitResult);
            if (!xsxx.isEmpty()) {
                return DaoUtils.buildParamMap(
                        "pass", false
                        , "msg", "系数控制失败，请联系管理员"
                        , "restProducts", restProducts
                        , "productInfo", productInfo
                        //, "calcAndCheckShippingQty", calcAndCheckShippingQty
                        , "finalSplitResult", finalSplitResult
                );
            }
//            boolean isCjRdcOnly = !KhUtil.caniUseGMLgort(KhUtil.isRdcOrder(orderMasterType),clientid);
//            if(isCjRdcOnly) {//临时仓不用调拨
//                for(Object row: finalSplitResult) {
//                    ((Map)row).put("isForceNoChangeLoadPoint",true);
//                }
//            }

            List<Map> getPlanListWithBingId = Arrays.asList();//当前已经不需要在初步分车处理计划单号生成规则  //baseMapper.getPlanListWithBingId(DaoUtils.buildParamMap("orderId", orderId));
            //装运点、类型、火车分组
//            if(isRdcX){
//                String flgort = KhUtil.getRdcAllotLgort(orderMasterType);
//                if(StringUtils.isNotBlank(flgort)) {
//                    finalSplitResult.forEach(r -> ((Map) r).put("rdcCalcLgort", flgort));
//                }
//            }
            if(isSpOutShippingNo){//走跟下面相反的模式，先非外仓分单，再检测能否用外仓atp替代
                List<Map> outAtp = (List<Map>) ctx.get("outAtp");
                Map<String, List<Map>> outProduct = outAtp.stream().collect(Collectors.groupingBy(r -> getStrFromMap(r, "productid")));
                Map<String, List<Map>> outProductAtpMap = outAtp.stream().collect(Collectors.groupingBy(r ->
                        String.format("%s-%s-%s",
                                getStrFromMap(r, "productid"),
                                getStrFromMap(r, "werks"),
                                getStrFromMap(r, "lgort")
                        )
                ));
                List<Map> normalCars = finalSplitResult;
                if(normalCars!=null && !normalCars.isEmpty()){
                    AtomicInteger idx = new AtomicInteger(0);
                    normalCars.forEach(r->{
                        idx.incrementAndGet();
//                        String planDate = getStrFromMap(r, "planDate");
                        String odPlanDate = getStrFromMap(od.get(0),"plandate");
                        List<Map> details = (List<Map>) r.get("details");
                        boolean isAllOutProd = !details.stream().filter(d->!outProduct.containsKey(getStrFromMap(d,"productid"))).findFirst().isPresent();
                        log.info("isAllOutProd-{}-{}-{}",orderId,idx.get(),isAllOutProd);
                        if(isAllOutProd){
                            Map<String,Integer> atpChange = new HashMap();
                            Map<String,List<Map>> atpChangeDetail = new HashMap();
                            List<String> planDateChange = new ArrayList();
                            boolean isAllOutAtpOk = !details.stream().filter(d-> {
                                boolean ret = false;
                                String productId = getStrFromMap(d,"productid");
                                int qty = getIntegerFromMap(d,"qty");
                                Map okAtp = outProduct.get(productId).stream().sorted(Comparator.comparing(ar -> getStrFromMap(ar, "atpdate")))
                                        .filter(ar -> {
                                            String atpdate = getStrFromMap(ar,"atpdate");
                                            String nfactory = getStrFromMap(ar,"werks");
                                            String nstore = getStrFromMap(ar,"lgort");
                                            String akey = String.format("%s-%s-%s",productId,nfactory,nstore);
                                            int val = getIntegerFromMap(atpChange,akey);
                                            int atp = Math.max(0,getIntegerFromMap(ar,"atp")-val);
                                            boolean aret = KhUtil.isOutBetterAtpDate(odPlanDate,atpdate)
                                                    && qty<=atp
                                                    ;
                                            if(aret){
                                                atpChange.put(akey,getIntegerFromMap(atpChange,akey)+qty);
                                                if(!atpChangeDetail.containsKey(akey)){
                                                    atpChangeDetail.put(akey,new ArrayList());
                                                }
                                                atpChangeDetail.get(akey).add(d);
                                                planDateChange.add(atpdate);
                                            }
                                            return aret;
                                        }).findFirst().orElse(null);
                                ret = okAtp!=null;
                                if(!ret){
                                    log.info("notokAtp-{}-{}-{}",orderId,productId,qty);
                                }
                                return !ret;
                            }).findFirst().isPresent();
                            log.info("isAllOutAtpOk-{}-{}",orderId,isAllOutAtpOk);
                            if(isAllOutAtpOk){
                                String fplanDate = planDateChange.stream().sorted(Comparator.reverseOrder()).findFirst().get();
                                r.put("planDate",fplanDate);
                                r.put("isOutCar",true);
                                atpChange.entrySet().forEach(e->{
                                    int val = e.getValue();
                                    outProductAtpMap.get(e.getKey()).forEach(v->{
                                        v.put("atp",Math.max(0,getIntegerFromMap(v,"atp")-val));
                                    });
                                });
                                atpChangeDetail.entrySet().forEach(e->{
                                    String[] arr = e.getKey().split("-");
                                    String nfactory = arr[1];
                                    String nstore = arr[2];
                                    e.getValue().forEach(ev->ev.put("calclgort",String.format("%s-%s",nfactory,nstore)));
                                });
                            }
                        }
                    });
                }
            }
            Map<String, List<AtpStoreItem>> storeMap = atpStoreItemMapper.selectList(Wrappers.<AtpStoreItem>lambdaQuery().eq(AtpStoreItem::getState, "01")).stream().collect(Collectors.groupingBy(r -> r.getId().toString()));
            OrderSplitControlUtils.setCtypeByOdIntoFinalSplitResult(finalSplitResult, od, storeMap);//写入ctype和factorys
            OrderSplitControlUtils.calcFinalSplitResultDetailMsgAndRestSum(finalSplitResult,productMap,splitZl,splitSpMin,splitSpMax,ulimit,od,storeMap);
            List<Map> nextdata = OrderSplitControlUtils.finalSplitResult2nextdata(tpdetails,fullAtpDbrows4nextdata, finalSplitResult, shippingQtySp, inorderId, loadPointCfgs, getPlanListWithBingId,xspmin,xspmax
                    ,splitTypeData,orderMasterType,productMap
            );
            pass = nextdata.size() > 0;//分出一车就算成功 分车有剩余，也调后续的接口
            if(tpdetails.size()>0) {
                restProducts = OrderSplitControlUtils.calcRest(tpdetails,msgs,productMap,splitZl,splitSpMin,splitSpMax,false,"qty");
                restProducts.put("pass",false);
            }
            if(pass) {
                Map genLoadPointMap = genLoadPointMap();
                nextdata.stream().filter(r->r.containsKey("isOutCar") && (Boolean)r.get("isOutCar")).forEach(r->{
                    ((List<Map>)r.get("splitDetails")).stream().forEach(dr->{
                        boolean isOut = KhUtil.isOutStore(getStrFromMap(dr,"factory"),getStrFromMap(dr,"store"));
                        boolean isOldOut = KhUtil.isOutStore(getStrFromMap(dr,"oldFactory"),getStrFromMap(dr,"oldStore"));
                        if(isOldOut){
                            dr.put("factory",getStrFromMap(dr,"oldFactory"));
                            dr.put("store",getStrFromMap(dr,"oldStore"));
                            dr.put("loadPoint",getStrFromMap(dr,"oldLoadPoint"));
                        }
                        else if(!isOut){
                            dr.put("oldFactory",getStrFromMap(dr,"factory"));
                            dr.put("oldStore",getStrFromMap(dr,"store"));
                            dr.put("oldLoadPoint",getStrFromMap(dr,"loadPoint"));
                            String[] outStore = KhUtil.getOutStore(getStrFromMap(dr,"oldFactory"),getStrFromMap(dr,"oldStore")).split(",");
                            dr.put("factory",outStore[0]);
                            dr.put("store",outStore[1]);
                            dr.put("loadPoint",getStrFromMap((Map) genLoadPointMap.get(DaoUtils.getValuesStr(outStore[0], outStore[1])), "loadPoint"));
                        }
                    });
                });
                List nextatp = OrderSplitControlUtils.genNextAtp(fullAtpDbrows);
                if(!hasOutCar) {
                    RedisUtils.set(RedisKeyConstants.SPLIT_ORDER_TEMP_DATA + orderId, nextdata);
                    RedisUtils.set(RedisKeyConstants.SPLIT_ORDER_ATPAFTER_TEMP_DATA + orderId, nextatp);
                    RedisUtils.set(RedisKeyConstants.SPLIT_ORDER_PRODUCTINFO_TEMP_DATA + orderId, productInfo);
                }


                if(!isNotInSplitTypeMode && splitTypeData.containsKey("lgortChangeMap")){
                    Map lgortChangeMap = (Map) splitTypeData.get("lgortChangeMap");//装运点计算时写入
                    List<Map> slgortDetails = (List<Map>) splitTypeData.get("lgortDetails");
//                    Map gplmap = genLoadPointMapByCalcLgort();
//                    Map genLoadPointMap = genLoadPointMap();

                    //修正关联计划单的装运点，调拨后续走汇总调拨计算
                    List<Map> ulist = slgortDetails.stream().filter(r -> r.containsKey("isNeedUpdate") && (Boolean) r.get("isNeedUpdate")).collect(Collectors.toList());
                    if(!ulist.isEmpty()) {
//                        ulist.forEach(r -> {
//                            ((IService) planOrderDetailsService).update(Wrappers.update()
//                                    .set("factory", r.get("factory")).set("store", r.get("store"))
//                                    .set("oldfactory", r.get("oldfactory")).set("oldstore", r.get("oldstore"))
//                                    .eq("nid", r.get("nid")));
//                        });
//                        ((Map<String, Map>) DaoUtils.list2map(ulist, true, "poid")).values().forEach(r -> {
//                            ((IService) planOrderMasterService).update(Wrappers.update()
//                                    .set("loadPoint", r.get("loadPoint"))
//                                    .eq("poid", r.get("poid")));
//                            log.info("lgortChange-,orderId{},loadPoint{},poid{}", orderId, r.get("loadPoint"), r.get("poid"));
//                        });
                        splitTypeData.put("spupdateTime", DateUtils.getCurrentDateTime());
                    }
                    RedisUtils.set(RedisKeyConstants.SPLIT_TYPE_DATA + orderId, splitTypeData);
                }

                boolean enableCheck = true;
                if(pass && enableCheck){
                    boolean checkPass = true;
                    List<Map> getOrderDetailsGroupbyEpidCtypes = baseMapperGetOrderDetailsGroupbyEpidCtypeWithPlan(orderId);// baseMapper.getOrderDetailsGroupbyEpidCtypes(Arrays.asList(DaoUtils.buildParamMap("orderId",orderId)));
                    Map getOrderDetailsMapByProductId = DaoUtils.list2map(getOrderDetailsGroupbyEpidCtypes,false,"productid","orderid");
                    for(Object key: getOrderDetailsMapByProductId.keySet()) {
                        int sqty = 0;
                        for(Map row: (List<Map>)getOrderDetailsMapByProductId.get(key)){
                            sqty+=getDecimalFromMap(row,"qty");
                        }
                        getOrderDetailsMapByProductId.put(key,sqty);
                    }
                    for(Map car: (List<Map>)nextdata){
                        Map productDetail = new HashMap();
                        for(Map p: (List<Map>)car.get("splitDetails")){
                            String productid = getStrFromMap(p,"productId");
                            String loadpoint = getStrFromMap(p,"loadPoint");
                            double qty = getDecimalFromMap(p,"qty");
                            String pkey = productid+"_"+loadpoint;
                            productDetail.put(pkey,getDecimalFromMap(productDetail,pkey)+qty);
                        }
                        List productDetailList = new ArrayList();
                        for(Object pkey: productDetail.keySet()) {
                            String[] pkeyarr = pkey.toString().split("_");
                            String productid = pkeyarr[0];
                            String loadpoint = pkeyarr.length<=1?"":pkeyarr[1];
                            productDetailList.add(DaoUtils.buildParamMap("productid",productid
                                    ,"qty",getDecimalFromMap(productDetail,pkey)
                                    ,"pallet", getDecimalFromMap((Map)productMap.get(productid),"pallet")
                                    ,"orderId",orderId
                                    ,"loadpoint",loadpoint
                                    )
                            );
                        }
                        boolean flag = PlanOrderCheckUtils.checkQty(productDetailList, getOrderDetailsMapByProductId);
                        checkPass=checkPass&&flag;
                        if(!flag){
                            log.info("WARNBIZ-CHECKANDSPLITORDER{} {}",orderId,productDetailList);
                        }
                    }
                    if(!checkPass){
                        for(Map row: (List<Map>)finalSplitResult){
                            log.info("WARNBIZ-CHECKANDSPLITORDER{} {}",orderId,row.get("restmsg"));
                            log.info("WARNBIZ-CHECKANDSPLITORDER{} {}",orderId,row.get("detailMsg"));
                        }
                    }
                }
            }
        }
        else {
            for(Map row: (List<Map>)finalSplitResult){
                log.info("WARNBIZ-CHECKANDSPLITORDERxx{} {}",orderId,row.get("restmsg"));
                log.info("WARNBIZ-CHECKANDSPLITORDERxx{} {}",orderId,row.get("detailMsg"));
            }
            msgs.clear();
            msgs.add(String.format("分单失败，请尝试%s产品后再保存确认!", isNeedAdd?"增加":"减少"));
            restProducts.clear();
        }
        tpdetails = (List) restProducts.get("details");
        boolean containRest = tpdetails!=null && tpdetails.size()>0;
        if(containRest){
            msgs.add("分单成功，但有剩余产品未分！");
        }
        if(pass && systemConfig.checkIsTestOnly()){
            printCar(finalSplitResult);
        }

        Map r = DaoUtils.buildParamMap(
                "pass", pass
                , "msg", msgs
                , "restProducts", restProducts
                , "productInfo", productInfo
                , "finalSplitResult", finalSplitResult
                , "demands", demands
        );
        if(!isNotInSplitTypeMode){
            if(null!=msgs){
                msgs.clear();
            }
        }
        if (pass) {
            //信用检测
            //Map resultMap = checkCreditBizService.judgeCredit(orderId);
        }
        return r;
    }